#ifndef _LIBPARTED_H_
#define _LIBPARTED_H_

#include <basic_types.h>


/* We can address 2^63 sectors */
typedef long long PedSector;

/* A cylinder-head-sector geometry. */
typedef struct _PedCHSGeometry
{
	long long	cylinders;
	int 		heads;
	int 		sectors;	/* sectors per track */
} PedCHSGeometry;

/* Partition types */
typedef enum
{
	PED_PARTITION_NORMAL		= 0x00,
	PED_PARTITION_LOGICAL		= 0x01,
	PED_PARTITION_EXTENDED		= 0x02,
	PED_PARTITION_FREESPACE 	= 0x04,
	PED_PARTITION_METADATA		= 0x08
} PedPartitionType;

/* Geometry of the partition */
typedef struct _PedGeometry
{
	PedSector	start;
	PedSector	length;
	PedSector	end;
} PedGeometry;

typedef struct _PedDisk PedDisk;
typedef struct _PedPartition PedPartition;

/* PedPartition structure represents a partition. */
struct _PedPartition
{
	PedPartition	   *prev;
	PedPartition	   *next;
	
	PedDisk 		   *disk;
	PedGeometry 		geom;
		
	int					num;
	PedPartitionType	type;

	int 				part_id;

	PedPartition	   *part_list; /* Only used for an extended partition. The list
									  of logical partitions and free space within 
									  the extended partition. */

	void			   *priv;
};

/* A whole disk, eg. /dev/hda, not /dev/hda3 */
struct _PedDisk
{
	PedCHSGeometry		geom;			/* disk geometry */

	int 				sector_size;	/* sector size */
	long long			length; 		/* disk length, measured in sector */

	PedPartition	   *part_list;		/* list of partitions. Access with 
										   ped_disk_next_partition() */
	int 				pri_part_num;	/* primary partitions number */
	int 				ext_part_num;	/* extended partitions number */
	int 				log_part_num;	/* logical partitions number */
	
	char				path[32];		/* disk path, eg. /dev/hda */
	int					dev_fd;			/* device file descriptor for read/write*/

	int					update_mode;
	int 				dirty;
};

typedef enum
{
	PED_FS_TYPE_NONE = 0,
	PED_FS_TYPE_FAT12,
	PED_FS_TYPE_FAT16,
	PED_FS_TYPE_FAT32,
	PED_FS_TYPE_NTFS
} PedFileSystemType;

PedSector ped_round_down_to(PedSector sector, PedSector grain_size);
PedSector ped_round_up_to(PedSector sector, PedSector grain_size);
PedSector ped_round_to_nearest(PedSector sector, PedSector grain_size);

extern int ped_partiton_priv_init(PedPartition *part, void *buf, int size);
extern int ped_partiton_priv_destroy(PedPartition *part);

extern PedPartition *ped_disk_extended_partition(const PedDisk *disk);
extern PedPartition *ped_disk_next_partition(const PedDisk *disk, 
											 const PedPartition *part);
extern PedPartition *ped_disk_add_partition(PedDisk *disk, PedPartitionType part_type,
		PedFileSystemType fs_type, PedSector start, PedSector length);
extern int ped_disk_delete_partition(PedDisk *disk, PedPartition *part);

extern PedDisk *ped_disk_new(const char *disk_path);
extern int ped_disk_commit(PedDisk *disk);
extern int ped_disk_destroy(PedDisk *disk);
extern void ped_disk_print(const PedDisk *disk);

#endif /* _LIBPARTED_H_ */
